package com.magold.skill;

import org.andengine.entity.modifier.RotationModifier;
import org.andengine.entity.shape.IShape;
import org.andengine.extension.physics.box2d.util.constants.PhysicsConstants;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.magold.logic.LogicComponentFinder;
import com.magold.physics.MagoldPhysicsConnector;
import com.magold.skill.BaseSkill.SkillListener;

public class SprintSkill extends BaseSkill implements SkillListener {
	public static final float DEFAULT_VELOCITY = 250 / PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT;
	private Body mForceTargetBody;
	private float mVelocity;
	private float mOmega;
	private Vector2 mDirection;
	private RotationModifier mRotationModifier;
	
	public SprintSkill(Body pForceTargetBody) {
		this(pForceTargetBody, DEFAULT_VELOCITY);
	}
	
	public SprintSkill(Body pForceTargetBody, float pVelocity) {
		mForceTargetBody = pForceTargetBody;
		
		mVelocity = pVelocity;
		mDirection = new Vector2(1, 0);
		
		addSkillListener(this);
		
		mRotationModifier = new RotationModifier(0.5f, 0, 0);
	}
	
	@Override
	protected void onSkillLaunching(float pSecondsElapsed) {
		mForceTargetBody.setLinearVelocity(mDirection.x * mVelocity, mDirection.y * mVelocity);
		
		float angleABS = Math.abs(getAngle());
		float omega = 0;
		if (angleABS < 1 || 180 - angleABS < 1) {
			return;
		} else if (angleABS < 3 || 180 - angleABS < 3) {
			float angle = angleABS < 3 ? 0 : (float) Math.PI;
		 	mForceTargetBody.setTransform(mForceTargetBody.getPosition(), angle);
		} else {
			omega = mOmega;
		}
		
		mForceTargetBody.setAngularVelocity(omega);
	}
	
	@Override
	public void onStop(BaseSkill pSkill) {
		MagoldPhysicsConnector connector = LogicComponentFinder.findConnector(mForceTargetBody);
		connector.setGravityScale(1);
		connector.getShape().unregisterEntityModifier(mRotationModifier);
		connector.setUpdateRotation(true);
	}
	
	@Override
	public void onLaunch(BaseSkill pSkill) {
		if (pSkill != this) return;
		
		Vector2 v = mForceTargetBody.getLinearVelocity();
		
		mDirection.set(v.x >= -0.1f ? 1 : -1, 0);
		
		MagoldPhysicsConnector connector = LogicComponentFinder.findConnector(mForceTargetBody);
		connector.setGravityScale(0);
		
		connector.setUpdateRotation(false);
		mForceTargetBody.setTransform(mForceTargetBody.getPosition(), 0);
		IShape shape = connector.getShape();
		
		mRotationModifier.reset(0.5f, getAngle(), 0);
		shape.registerEntityModifier(mRotationModifier);
	}
	
	/**
	 * 
	 * @return degree (-180, 180]
	 */
	private float getAngle() {
		float angle = mForceTargetBody.getAngle();
		float degree = (float) Math.toDegrees(angle);
		degree %= 360;
		
		if (degree > 180) {
			degree -= 360;
		} else if (degree <= -180) {
			degree += 360;
		}
		
		return degree;
	}
	
	public Vector2 getDirection() {
		return mDirection;
	}
	
}
